Skip to content

Conversation

@Wunka
Copy link
Contributor

@Wunka Wunka commented Jan 7, 2026

Splitted of from #2324
First of two Payloads that need change to accept slices as destinations for the split of the hotbar to work.

Even if the split of the hotbar is not accepted this could still be necessary. See comment: #2324 (review)

I don't like the allocation solution so if anybody has a better solution it would be very welcome.

The renaming to destinations is to use dest in the for loops and to show that this is different to the other payloads dest parameter

@Wunka Wunka changed the title Deposit slice DepositToAny slice for the destination Jan 7, 2026
@Argmaster Argmaster moved this to Low Priority in PRs to review Jan 8, 2026
@Wunka
Copy link
Contributor Author

Wunka commented Jan 8, 2026

I changed the priority system between the different destinations to align with #2324 (review)
For testing purposes you can just use #2324 as I have merged this branch into there. What I used for testing is a chest and I just shift-clicked moved items between the chest and my hotbar/inventory

Copy link
Member

@IntegratedQuantum IntegratedQuantum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I immediately see problems with the allocation strategy, please fix them before I review the rest of the code.

if(self.dest.type == .creative) return;
if(self.dest.type == .crafting) return;
if(self.dest.type == .workbench) return;
defer if(self.owned) main.stackAllocator.free(self.destinations);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

command may run multiple times on the client side, freeing here causes a double free. Instead you can free this in finalize.
Also the stackAllocator is a poor choice, only use the stackAllocator for local allocations, this allocation persists for multiple threads and likely will be ran from a different thread as well.

Also the allocator shouldn't be hardcoded here, instead the caller should pass it.

Lastly who even owns the memory in the other case? How do you keep track of something that gets used possible many frames after passing it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

command may run multiple times on the client side, freeing here causes a double free. Instead you can free this in finalize. Also the stackAllocator is a poor choice, only use the stackAllocator for local allocations, this allocation persists for multiple threads and likely will be ran from a different thread as well.

done changed to the globalAllocator which is used for other payloads

Also the allocator shouldn't be hardcoded here, instead the caller should pass it.

so should I change the finalize to parse over the globalAllocator? That looks better to me at least.

Lastly who even owns the memory in the other case? How do you keep track of something that gets used possible many frames after passing it?

Yeah you are right there... I will look into how I want to solve that. I could maybe just dupe the slice so that its always owned? But I don't want to that in gui.zig where depositToAny is called... I will sleep over it and look tomorrow at the code again.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so should I change the finalize to parse over the globalAllocator? That looks better to me at least.

No, it should be passed on creation, since the finalize call is already really disconnected from the creation.
This would prevent accidentally using mismatched allocators.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switched the owned variable with an allocator. Also did the other issue with an dupe so it should now always be owned.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also consider making a separate .init function that allocates everything inside. Then I would be fine with not having the allocator stored since it's all used locally.

@IntegratedQuantum IntegratedQuantum moved this from Low Priority to In review in PRs to review Jan 8, 2026
if(self.dest.type == .creative) return;
if(self.dest.type == .crafting) return;
if(self.dest.type == .workbench) return;
if(self.destinations.len == 0) return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When would this even happen?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A modified Client can send anything. I just want to put a check in before it later causes bugs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is about safety of client data, then you should put this check in the deserialization function.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Client data should generally be sanitized during or immediately after receiving.

for(self.dest._items, 0..) |*destStack, destSlot| {
if(destStack.item == .null and selectedEmptySlot == null) {
selectedEmptySlot = @intCast(destSlot);
var selectedEmptyInv: u8 = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why limit this to a u8? It should be usize, there is nothing gained by using a u8, other than future bugs from the intCast.


fn serialize(self: DepositToAny, writer: *utils.BinaryWriter) void {
writer.writeEnum(InventoryId, self.dest.id);
writer.writeInt(u8, @intCast(self.destinations.len));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a varint and send a usize
Putting an arbitrary limit on the number and crashing when exceeded is not helpful.
If you want to limit this then you should have a good reason for it, and 256 might definitely be in reach for a deposit to nearby chests function.

if(emptySlot != null and (selectedEmptySlot == null or (hasItem and !selectedEmptyInvHasItem))) {
selectedEmptySlot = emptySlot;
selectedEmptyInv = @intCast(destInv);
selectedEmptyInvHasItem = hasItem;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is different from the behavior suggested in #2324 (review), here you seem to be first topping off partially filled stacks in the other inventories.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all done

Copy link
Member

@IntegratedQuantum IntegratedQuantum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some small things, otherwise it seems reasonable

@Wunka
Copy link
Contributor Author

Wunka commented Jan 10, 2026

rest of the requested changes are also done

@IntegratedQuantum IntegratedQuantum merged commit a4263eb into PixelGuys:master Jan 11, 2026
1 check passed
@Wunka Wunka deleted the DepositSlice branch January 11, 2026 10:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants